/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package uk.co.droidinactu.common.controller;

import java.io.File;
import java.util.ArrayList;

import uk.co.droidinactu.common.db.AbstractDatabaseHelper;
import uk.co.droidinactu.common.db.AbstractDatabaseHelperFactory;
import uk.co.droidinactu.common.db.AbstractDbConstants;
import uk.co.droidinactu.common.file.FileUtilities;
import uk.co.droidinactu.common.model.AbstractDataObj;
import uk.co.droidinactu.common.model.Preference;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.provider.BaseColumns;

/**
 * 
 * @author andy
 */
public abstract class AbstractDatabaseController {

	private android.content.Context context;
	private AbstractDbConstants dbConstants;
	private AbstractDatabaseHelper dbhelper;
	private SQLiteDatabase myDB = null;

	public AbstractDatabaseController() {
	}

	public void backupDb(final String dataDir) {

		try {
			final String dbName = getDatabaseName() + getDatabaseExtension();
			final File extDir = Environment.getExternalStorageDirectory();
			final File appDir = Environment.getDataDirectory();

			final File dbFile = new File(dataDir + dbName);
			final File dbFileBackup = new File(extDir + File.separator + "dbBak" + dbName);

			if (dbFile.exists()) {
				FileUtilities.copyFile(dbFile, dbFileBackup);
			}
		} catch (final Exception e) {
			e.printStackTrace();
		}
	}

	public void closeDatabase() {
		if (myDB != null) {
			myDB.close();
		}
		myDB = null;
	}

	public void commit() {
		if (myDB == null) {
			openDatabase();
		}
	}

	protected void createCommonTables() {
		this.executeSql(new Preference().getSqlCreate());
	}

	public void createSampleData() {
		final Preference pref2 = new Preference("homepage", "http://www.aspellclark.org.uk/");
		this.insert(pref2.getTableName(), null, pref2.getContentValues());
		final Preference pref3 = new Preference("authoremail", "andy@aspellclark.org.uk");
		this.insert(pref3.getTableName(), null, pref3.getContentValues());
		final Preference pref1 = new Preference("author", "Andy Aspell-Clark");
		this.insert(pref1.getTableName(), null, pref1.getContentValues());
	}

	public long delete(final AbstractDataObj obj) {
		return myDB.delete(obj.getTableName(), BaseColumns._ID + "=?", new String[] { obj
				.getUniqueIdentifier().toString() });
	}

	public long delete(final String tableName, final Integer objId) {
		return myDB.delete(tableName, BaseColumns._ID + "=?", new String[] { objId.toString() });
	}

	public void deleteDatabaseFile() {
		try {
			closeDatabase();
		} catch (final Exception e) {
		}
		final String dbName = getDatabaseName() + getDatabaseExtension();
		final File dbFile = new File(dbName);
		if (dbFile.exists()) {
			dbFile.delete();
		}
	}

	public void executeSql(final ArrayList<String> sqlStmts) {
		for (final String stmt : sqlStmts) {
			this.executeSql(stmt);
		}
	}

	public void executeSql(final String sqlStmt) {
		try {
			if (myDB == null) {
				openDatabase();
			}
			myDB.execSQL(sqlStmt);
		} catch (final Exception e) {
			System.out.println(e.getMessage());
		}
	}

	public android.content.Context getContext() {
		return context;
	}

	private String getDatabaseExtension() {
		return ".db";
	}

	public abstract String getDatabaseName();

	public void initialise(final android.content.Context cntxt, final AbstractDbConstants dbCnstants,
			final AbstractDatabaseHelperFactory dbHlprFactory) {
		context = cntxt;
		dbhelper = dbHlprFactory.getDatabaseHelper(cntxt, dbCnstants);
		openDatabase();
	}

	public long insert(final AbstractDataObj obj) {
		return this.insert(obj.getTableName(), null, obj.getContentValues());
	}

	public long insert(final String tableName, final String nullObjHack, final ContentValues contentValues) {
		return myDB.insert(tableName, nullObjHack, contentValues);
	}

	/**
	 * This function opens the database in read/write mode.
	 */
	public boolean openDatabase() {
		if (myDB == null) {
			myDB = dbhelper.getWritableDatabase();
		}
		return (myDB == null) ? false : true;
	}

	/**
	 * This method reads in data from the database and puts it into a cursor.
	 * 
	 * @param sqlStmt
	 *            is the sql statment which will be executed to read the
	 *            database.
	 * @return a cursor containing the selected rows.
	 */
	public Cursor selectData(final String sqlStmt) {
		if (myDB == null) {
			openDatabase();
		}
		final Cursor c = myDB.rawQuery(sqlStmt, null);
		return c;
	}

	public void setContext(final android.content.Context context) {
		this.context = context;
	}

	public void update(final AbstractDataObj obj) {
		this.update(obj.getTableName(), obj.getContentValues(), obj.getUniqueIdentifier());
	}

	public long update(final String tableName, final ContentValues contentValues, final Long objId) {
		return myDB.update(tableName, contentValues, BaseColumns._ID + "=?",
				new String[] { objId.toString() });
	}
}
